from django.utils.deprecation import MiddlewareMixin
from auth_app.models import UserModel
from utils.messages import Err_Auth_Verify, Error_Res
from Alpha.settings import auth_token_name
from utils.token import decode_token
import datetime, time
import json, traceback


class AuthTokenVerifyMiddleware(MiddlewareMixin):
    '''
    根据url对请求进行用户验证
    一、url不需要用户认证
      --请求通过
    二、url需要用户验证
      --没Token：请求失败，返回错误信息
      --Token解析失败：请求失败，返回错误信息
      --Token解析成功：验证token有效性,request新增USER_INFO属性，值为已经encode的user_info，请求通过
    '''

    def __init__(self, get_response=None):
        super().__init__(get_response)
        self.non_verify_url = self._get_urls()  # 不需要验证的url

    def _get_urls(self):
        u = []

        from auth_app.urls import urls as auth_urls
        from celery_app.urls import urls as celery_urls
        from config_app.urls import urls as config_urls
        from interface_test_app.urls import urls as interface_urls

        u.extend([i[0] for i in auth_urls if not i[3]])
        u.extend([i[0] for i in celery_urls if not i[3]])
        u.extend([i[0] for i in config_urls if not i[3]])
        u.extend([i[0] for i in interface_urls if not i[3]])

        return u

    def process_request(self, request):

        req_url = request.path[1:]
        if (req_url not in self.non_verify_url):  # options请求、无认证的接口 直接pass
            try:  # 判断header中是否有User-Token
                now = time.time()
                token = request.headers[auth_token_name]
                payload = decode_token(token)
                effect_timestamp, expire_timestamp = payload['effect_timestamp'], payload['expire_timestamp']
                if (effect_timestamp < now) and (expire_timestamp > now):  # token有效
                    user_info = payload['user_info']
                    user_qs = UserModel.objects.filter(id=user_info['usr_id'])
                    if user_qs:
                        user_obj = user_qs[0]
                        if user_obj.token_key == payload['token_key']:
                            request.USER_INFO = user_info
                        else:
                            return Err_Auth_Verify()
                    else:
                        return Err_Auth_Verify()
                else:
                    return Err_Auth_Verify()
            except:
                return Err_Auth_Verify()
        else:
            request.USER_INFO = {}


class ReqBodyEncoderMiddleware(MiddlewareMixin):
    '''
    request.body反序列化
    反序列化成功后添加新属性payload
    '''

    def process_request(self, request):
        body = request.body
        payload = {}
        if body:
            try:
                payload = json.loads(request.body)
            except:
                payload = {}
        request.payload = payload


class ErrorMiddleware(MiddlewareMixin):
    def process_exception(self, request, exception):
        # 只有在视图函数中出现异常了才执行
        '''
        :param request: HttpRequest对象
        :param exception: 视图函数异常产生的 Exception 对象
        '''
        print(traceback.format_exc())
        print(exception)
        return Error_Res(exception)
